<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>The source code</title>
  <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
  <script type="text/javascript" src="../prettify/prettify.js"></script>
  <style type="text/css">
    .highlight { display: block; background-color: #ddd; }
  </style>
  <script type="text/javascript">
    function highlight() {
      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
    }
  </script>
</head>
<body onload="prettyPrint(); highlight();">
  <pre class="prettyprint lang-js"><span id='Ext-EventObject'>/**
</span> * @class Ext.EventObject

Just as {@link Ext.core.Element} wraps around a native DOM node, Ext.EventObject
wraps the browser's native event-object normalizing cross-browser differences,
such as which mouse button is clicked, keys pressed, mechanisms to stop
event-propagation along with a method to prevent default actions from taking place.

For example:

    function handleClick(e, t){ // e is not a standard event object, it is a Ext.EventObject
        e.preventDefault();
        var target = e.getTarget(); // same as t (the target HTMLElement)
        ...
    }

    var myDiv = {@link Ext#get Ext.get}(&quot;myDiv&quot;);  // get reference to an {@link Ext.core.Element}
    myDiv.on(         // 'on' is shorthand for addListener
        &quot;click&quot;,      // perform an action on click of myDiv
        handleClick   // reference to the action handler
    );

    // other methods to do the same:
    Ext.EventManager.on(&quot;myDiv&quot;, 'click', handleClick);
    Ext.EventManager.addListener(&quot;myDiv&quot;, 'click', handleClick);

 * @singleton
 * @markdown
 */
Ext.define('Ext.EventObjectImpl', {
    uses: ['Ext.util.Point'],

<span id='Ext-EventObject-property-BACKSPACE'>    /** Key constant @type Number */
</span>    BACKSPACE: 8,
<span id='Ext-EventObject-property-TAB'>    /** Key constant @type Number */
</span>    TAB: 9,
<span id='Ext-EventObject-property-NUM_CENTER'>    /** Key constant @type Number */
</span>    NUM_CENTER: 12,
<span id='Ext-EventObject-property-ENTER'>    /** Key constant @type Number */
</span>    ENTER: 13,
<span id='Ext-EventObject-property-RETURN'>    /** Key constant @type Number */
</span>    RETURN: 13,
<span id='Ext-EventObject-property-SHIFT'>    /** Key constant @type Number */
</span>    SHIFT: 16,
<span id='Ext-EventObject-property-CTRL'>    /** Key constant @type Number */
</span>    CTRL: 17,
<span id='Ext-EventObject-property-ALT'>    /** Key constant @type Number */
</span>    ALT: 18,
<span id='Ext-EventObject-property-PAUSE'>    /** Key constant @type Number */
</span>    PAUSE: 19,
<span id='Ext-EventObject-property-CAPS_LOCK'>    /** Key constant @type Number */
</span>    CAPS_LOCK: 20,
<span id='Ext-EventObject-property-ESC'>    /** Key constant @type Number */
</span>    ESC: 27,
<span id='Ext-EventObject-property-SPACE'>    /** Key constant @type Number */
</span>    SPACE: 32,
<span id='Ext-EventObject-property-PAGE_UP'>    /** Key constant @type Number */
</span>    PAGE_UP: 33,
<span id='Ext-EventObject-property-PAGE_DOWN'>    /** Key constant @type Number */
</span>    PAGE_DOWN: 34,
<span id='Ext-EventObject-property-END'>    /** Key constant @type Number */
</span>    END: 35,
<span id='Ext-EventObject-property-HOME'>    /** Key constant @type Number */
</span>    HOME: 36,
<span id='Ext-EventObject-property-LEFT'>    /** Key constant @type Number */
</span>    LEFT: 37,
<span id='Ext-EventObject-property-UP'>    /** Key constant @type Number */
</span>    UP: 38,
<span id='Ext-EventObject-property-RIGHT'>    /** Key constant @type Number */
</span>    RIGHT: 39,
<span id='Ext-EventObject-property-DOWN'>    /** Key constant @type Number */
</span>    DOWN: 40,
<span id='Ext-EventObject-property-PRINT_SCREEN'>    /** Key constant @type Number */
</span>    PRINT_SCREEN: 44,
<span id='Ext-EventObject-property-INSERT'>    /** Key constant @type Number */
</span>    INSERT: 45,
<span id='Ext-EventObject-property-DELETE'>    /** Key constant @type Number */
</span>    DELETE: 46,
<span id='Ext-EventObject-property-ZERO'>    /** Key constant @type Number */
</span>    ZERO: 48,
<span id='Ext-EventObject-property-ONE'>    /** Key constant @type Number */
</span>    ONE: 49,
<span id='Ext-EventObject-property-TWO'>    /** Key constant @type Number */
</span>    TWO: 50,
<span id='Ext-EventObject-property-THREE'>    /** Key constant @type Number */
</span>    THREE: 51,
<span id='Ext-EventObject-property-FOUR'>    /** Key constant @type Number */
</span>    FOUR: 52,
<span id='Ext-EventObject-property-FIVE'>    /** Key constant @type Number */
</span>    FIVE: 53,
<span id='Ext-EventObject-property-SIX'>    /** Key constant @type Number */
</span>    SIX: 54,
<span id='Ext-EventObject-property-SEVEN'>    /** Key constant @type Number */
</span>    SEVEN: 55,
<span id='Ext-EventObject-property-EIGHT'>    /** Key constant @type Number */
</span>    EIGHT: 56,
<span id='Ext-EventObject-property-NINE'>    /** Key constant @type Number */
</span>    NINE: 57,
<span id='Ext-EventObject-property-A'>    /** Key constant @type Number */
</span>    A: 65,
<span id='Ext-EventObject-property-B'>    /** Key constant @type Number */
</span>    B: 66,
<span id='Ext-EventObject-property-C'>    /** Key constant @type Number */
</span>    C: 67,
<span id='Ext-EventObject-property-D'>    /** Key constant @type Number */
</span>    D: 68,
<span id='Ext-EventObject-property-E'>    /** Key constant @type Number */
</span>    E: 69,
<span id='Ext-EventObject-property-F'>    /** Key constant @type Number */
</span>    F: 70,
<span id='Ext-EventObject-property-G'>    /** Key constant @type Number */
</span>    G: 71,
<span id='Ext-EventObject-property-H'>    /** Key constant @type Number */
</span>    H: 72,
<span id='Ext-EventObject-property-I'>    /** Key constant @type Number */
</span>    I: 73,
<span id='Ext-EventObject-property-J'>    /** Key constant @type Number */
</span>    J: 74,
<span id='Ext-EventObject-property-K'>    /** Key constant @type Number */
</span>    K: 75,
<span id='Ext-EventObject-property-L'>    /** Key constant @type Number */
</span>    L: 76,
<span id='Ext-EventObject-property-M'>    /** Key constant @type Number */
</span>    M: 77,
<span id='Ext-EventObject-property-N'>    /** Key constant @type Number */
</span>    N: 78,
<span id='Ext-EventObject-property-O'>    /** Key constant @type Number */
</span>    O: 79,
<span id='Ext-EventObject-property-P'>    /** Key constant @type Number */
</span>    P: 80,
<span id='Ext-EventObject-property-Q'>    /** Key constant @type Number */
</span>    Q: 81,
<span id='Ext-EventObject-property-R'>    /** Key constant @type Number */
</span>    R: 82,
<span id='Ext-EventObject-property-S'>    /** Key constant @type Number */
</span>    S: 83,
<span id='Ext-EventObject-property-T'>    /** Key constant @type Number */
</span>    T: 84,
<span id='Ext-EventObject-property-U'>    /** Key constant @type Number */
</span>    U: 85,
<span id='Ext-EventObject-property-V'>    /** Key constant @type Number */
</span>    V: 86,
<span id='Ext-EventObject-property-W'>    /** Key constant @type Number */
</span>    W: 87,
<span id='Ext-EventObject-property-X'>    /** Key constant @type Number */
</span>    X: 88,
<span id='Ext-EventObject-property-Y'>    /** Key constant @type Number */
</span>    Y: 89,
<span id='Ext-EventObject-property-Z'>    /** Key constant @type Number */
</span>    Z: 90,
<span id='Ext-EventObject-property-CONTEXT_MENU'>    /** Key constant @type Number */
</span>    CONTEXT_MENU: 93,
<span id='Ext-EventObject-property-NUM_ZERO'>    /** Key constant @type Number */
</span>    NUM_ZERO: 96,
<span id='Ext-EventObject-property-NUM_ONE'>    /** Key constant @type Number */
</span>    NUM_ONE: 97,
<span id='Ext-EventObject-property-NUM_TWO'>    /** Key constant @type Number */
</span>    NUM_TWO: 98,
<span id='Ext-EventObject-property-NUM_THREE'>    /** Key constant @type Number */
</span>    NUM_THREE: 99,
<span id='Ext-EventObject-property-NUM_FOUR'>    /** Key constant @type Number */
</span>    NUM_FOUR: 100,
<span id='Ext-EventObject-property-NUM_FIVE'>    /** Key constant @type Number */
</span>    NUM_FIVE: 101,
<span id='Ext-EventObject-property-NUM_SIX'>    /** Key constant @type Number */
</span>    NUM_SIX: 102,
<span id='Ext-EventObject-property-NUM_SEVEN'>    /** Key constant @type Number */
</span>    NUM_SEVEN: 103,
<span id='Ext-EventObject-property-NUM_EIGHT'>    /** Key constant @type Number */
</span>    NUM_EIGHT: 104,
<span id='Ext-EventObject-property-NUM_NINE'>    /** Key constant @type Number */
</span>    NUM_NINE: 105,
<span id='Ext-EventObject-property-NUM_MULTIPLY'>    /** Key constant @type Number */
</span>    NUM_MULTIPLY: 106,
<span id='Ext-EventObject-property-NUM_PLUS'>    /** Key constant @type Number */
</span>    NUM_PLUS: 107,
<span id='Ext-EventObject-property-NUM_MINUS'>    /** Key constant @type Number */
</span>    NUM_MINUS: 109,
<span id='Ext-EventObject-property-NUM_PERIOD'>    /** Key constant @type Number */
</span>    NUM_PERIOD: 110,
<span id='Ext-EventObject-property-NUM_DIVISION'>    /** Key constant @type Number */
</span>    NUM_DIVISION: 111,
<span id='Ext-EventObject-property-F1'>    /** Key constant @type Number */
</span>    F1: 112,
<span id='Ext-EventObject-property-F2'>    /** Key constant @type Number */
</span>    F2: 113,
<span id='Ext-EventObject-property-F3'>    /** Key constant @type Number */
</span>    F3: 114,
<span id='Ext-EventObject-property-F4'>    /** Key constant @type Number */
</span>    F4: 115,
<span id='Ext-EventObject-property-F5'>    /** Key constant @type Number */
</span>    F5: 116,
<span id='Ext-EventObject-property-F6'>    /** Key constant @type Number */
</span>    F6: 117,
<span id='Ext-EventObject-property-F7'>    /** Key constant @type Number */
</span>    F7: 118,
<span id='Ext-EventObject-property-F8'>    /** Key constant @type Number */
</span>    F8: 119,
<span id='Ext-EventObject-property-F9'>    /** Key constant @type Number */
</span>    F9: 120,
<span id='Ext-EventObject-property-F10'>    /** Key constant @type Number */
</span>    F10: 121,
<span id='Ext-EventObject-property-F11'>    /** Key constant @type Number */
</span>    F11: 122,
<span id='Ext-EventObject-property-F12'>    /** Key constant @type Number */
</span>    F12: 123,
<span id='Ext-EventObject-property-WHEEL_SCALE'>    /**
</span>     * The mouse wheel delta scaling factor. This value depends on browser version and OS and
     * attempts to produce a similar scrolling experience across all platforms and browsers.
     * 
     * To change this value:
     * 
     *      Ext.EventObjectImpl.prototype.WHEEL_SCALE = 72;
     * 
     * @type Number
     * @markdown
     */
    WHEEL_SCALE: (function () {
        var scale;

        if (Ext.isGecko) {
            // Firefox uses 3 on all platforms
            scale = 3;
        } else if (Ext.isMac) {
            // Continuous scrolling devices have momentum and produce much more scroll than
            // discrete devices on the same OS and browser. To make things exciting, Safari
            // (and not Chrome) changed from small values to 120 (like IE).

            if (Ext.isSafari &amp;&amp; Ext.webKitVersion &gt;= 532.0) {
                // Safari changed the scrolling factor to match IE (for details see
                // https://bugs.webkit.org/show_bug.cgi?id=24368). The WebKit version where this
                // change was introduced was 532.0
                //      Detailed discussion:
                //      https://bugs.webkit.org/show_bug.cgi?id=29601
                //      http://trac.webkit.org/browser/trunk/WebKit/chromium/src/mac/WebInputEventFactory.mm#L1063
                scale = 120;
            } else {
                // MS optical wheel mouse produces multiples of 12 which is close enough
                // to help tame the speed of the continuous mice...
                scale = 12;
            }

            // Momentum scrolling produces very fast scrolling, so increase the scale factor
            // to help produce similar results cross platform. This could be even larger and
            // it would help those mice, but other mice would become almost unusable as a
            // result (since we cannot tell which device type is in use).
            scale *= 3;
        } else {
            // IE, Opera and other Windows browsers use 120.
            scale = 120;
        }

        return scale;
    })(),

<span id='Ext-EventObject-property-clickRe'>    /**
</span>     * Simple click regex
     * @private
     */
    clickRe: /(dbl)?click/,
    // safari keypress events for special keys return bad keycodes
    safariKeys: {
        3: 13, // enter
        63234: 37, // left
        63235: 39, // right
        63232: 38, // up
        63233: 40, // down
        63276: 33, // page up
        63277: 34, // page down
        63272: 46, // delete
        63273: 36, // home
        63275: 35 // end
    },
    // normalize button clicks, don't see any way to feature detect this.
    btnMap: Ext.isIE ? {
        1: 0,
        4: 1,
        2: 2
    } : {
        0: 0,
        1: 1,
        2: 2
    },

    constructor: function(event, freezeEvent){
        if (event) {
            this.setEvent(event.browserEvent || event, freezeEvent);
        }
    },

    setEvent: function(event, freezeEvent){
        var me = this, button, options;

        if (event == me || (event &amp;&amp; event.browserEvent)) { // already wrapped
            return event;
        }
        me.browserEvent = event;
        if (event) {
            // normalize buttons
            button = event.button ? me.btnMap[event.button] : (event.which ? event.which - 1 : -1);
            if (me.clickRe.test(event.type) &amp;&amp; button == -1) {
                button = 0;
            }
            options = {
                type: event.type,
                button: button,
                shiftKey: event.shiftKey,
                // mac metaKey behaves like ctrlKey
                ctrlKey: event.ctrlKey || event.metaKey || false,
                altKey: event.altKey,
                // in getKey these will be normalized for the mac
                keyCode: event.keyCode,
                charCode: event.charCode,
                // cache the targets for the delayed and or buffered events
                target: Ext.EventManager.getTarget(event),
                relatedTarget: Ext.EventManager.getRelatedTarget(event),
                currentTarget: event.currentTarget,
                xy: (freezeEvent ? me.getXY() : null)
            };
        } else {
            options = {
                button: -1,
                shiftKey: false,
                ctrlKey: false,
                altKey: false,
                keyCode: 0,
                charCode: 0,
                target: null,
                xy: [0, 0]
            };
        }
        Ext.apply(me, options);
        return me;
    },

<span id='Ext-EventObject-method-stopEvent'>    /**
</span>     * Stop the event (preventDefault and stopPropagation)
     */
    stopEvent: function(){
        this.stopPropagation();
        this.preventDefault();
    },

<span id='Ext-EventObject-method-preventDefault'>    /**
</span>     * Prevents the browsers default handling of the event.
     */
    preventDefault: function(){
        if (this.browserEvent) {
            Ext.EventManager.preventDefault(this.browserEvent);
        }
    },

<span id='Ext-EventObject-method-stopPropagation'>    /**
</span>     * Cancels bubbling of the event.
     */
    stopPropagation: function(){
        var browserEvent = this.browserEvent;

        if (browserEvent) {
            if (browserEvent.type == 'mousedown') {
                Ext.EventManager.stoppedMouseDownEvent.fire(this);
            }
            Ext.EventManager.stopPropagation(browserEvent);
        }
    },

<span id='Ext-EventObject-method-getCharCode'>    /**
</span>     * Gets the character code for the event.
     * @return {Number}
     */
    getCharCode: function(){
        return this.charCode || this.keyCode;
    },

<span id='Ext-EventObject-method-getKey'>    /**
</span>     * Returns a normalized keyCode for the event.
     * @return {Number} The key code
     */
    getKey: function(){
        return this.normalizeKey(this.keyCode || this.charCode);
    },

<span id='Ext-EventObject-method-normalizeKey'>    /**
</span>     * Normalize key codes across browsers
     * @private
     * @param {Number} key The key code
     * @return {Number} The normalized code
     */
    normalizeKey: function(key){
        // can't feature detect this
        return Ext.isWebKit ? (this.safariKeys[key] || key) : key;
    },

<span id='Ext-EventObject-method-getPageX'>    /**
</span>     * Gets the x coordinate of the event.
     * @return {Number}
     * @deprecated 4.0 Replaced by {@link #getX}
     */
    getPageX: function(){
        return this.getX();
    },

<span id='Ext-EventObject-method-getPageY'>    /**
</span>     * Gets the y coordinate of the event.
     * @return {Number}
     * @deprecated 4.0 Replaced by {@link #getY}
     */
    getPageY: function(){
        return this.getY();
    },
    
<span id='Ext-EventObject-method-getX'>    /**
</span>     * Gets the x coordinate of the event.
     * @return {Number}
     */
    getX: function() {
        return this.getXY()[0];
    },    
    
<span id='Ext-EventObject-method-getY'>    /**
</span>     * Gets the y coordinate of the event.
     * @return {Number}
     */
    getY: function() {
        return this.getXY()[1];
    },
        
<span id='Ext-EventObject-method-getXY'>    /**
</span>     * Gets the page coordinates of the event.
     * @return {Array} The xy values like [x, y]
     */
    getXY: function() {
        if (!this.xy) {
            // same for XY
            this.xy = Ext.EventManager.getPageXY(this.browserEvent);
        }
        return this.xy;
    },

<span id='Ext-EventObject-method-getTarget'>    /**
</span>     * Gets the target for the event.
     * @param {String} selector (optional) A simple selector to filter the target or look for an ancestor of the target
     * @param {Number/Mixed} maxDepth (optional) The max depth to search as a number or element (defaults to 10 || document.body)
     * @param {Boolean} returnEl (optional) True to return a Ext.core.Element object instead of DOM node
     * @return {HTMLelement}
     */
    getTarget : function(selector, maxDepth, returnEl){
        if (selector) {
            return Ext.fly(this.target).findParent(selector, maxDepth, returnEl);
        }
        return returnEl ? Ext.get(this.target) : this.target;
    },

<span id='Ext-EventObject-method-getRelatedTarget'>    /**
</span>     * Gets the related target.
     * @param {String} selector (optional) A simple selector to filter the target or look for an ancestor of the target
     * @param {Number/Mixed} maxDepth (optional) The max depth to search as a number or element (defaults to 10 || document.body)
     * @param {Boolean} returnEl (optional) True to return a Ext.core.Element object instead of DOM node
     * @return {HTMLElement}
     */
    getRelatedTarget : function(selector, maxDepth, returnEl){
        if (selector) {
            return Ext.fly(this.relatedTarget).findParent(selector, maxDepth, returnEl);
        }
        return returnEl ? Ext.get(this.relatedTarget) : this.relatedTarget;
    },

<span id='Ext-EventObject-method-correctWheelDelta'>    /**
</span>     * Correctly scales a given wheel delta.
     * @param {Number} delta The delta value.
     */
    correctWheelDelta : function (delta) {
        var scale = this.WHEEL_SCALE,
            ret = Math.round(delta / scale + 0.5);

        if (!ret &amp;&amp; delta) {
            ret = (delta &lt; 0) ? -1 : 1; // don't allow non-zero deltas to go to zero!
        }

        return ret;
    },

<span id='Ext-EventObject-method-getWheelDeltas'>    /**
</span>     * Returns the mouse wheel deltas for this event.
     * @return {Object} An object with &quot;x&quot; and &quot;y&quot; properties holding the mouse wheel deltas.
     */
    getWheelDeltas : function () {
        var me = this,
            event = me.browserEvent,
            dx = 0, dy = 0; // the deltas

        if (Ext.isDefined(event.wheelDeltaX)) { // WebKit has both dimensions
            dx = event.wheelDeltaX;
            dy = event.wheelDeltaY;
        } else if (event.wheelDelta) { // old WebKit and IE
            dy = event.wheelDelta;
        } else if (event.detail) { // Gecko
            dy = -event.detail; // gecko is backwards

            // Gecko sometimes returns really big values if the user changes settings to
            // scroll a whole page per scroll
            if (dy &gt; 100) {
                dy = 3;
            } else if (dy &lt; -100) {
                dy = -3;
            }

            // Firefox 3.1 adds an axis field to the event to indicate direction of
            // scroll.  See https://developer.mozilla.org/en/Gecko-Specific_DOM_Events
            if (Ext.isDefined(event.axis) &amp;&amp; event.axis === event.HORIZONTAL_AXIS) {
                dx = dy;
                dy = 0;
            }
        }

        return {
            x: me.correctWheelDelta(dx),
            y: me.correctWheelDelta(dy)
        };
    },

<span id='Ext-EventObject-method-getWheelDelta'>    /**
</span>     * Normalizes mouse wheel y-delta across browsers. To get x-delta information, use
     * {@link #getWheelDeltas} instead.
     * @return {Number} The mouse wheel y-delta
     */
    getWheelDelta : function(){
        var deltas = this.getWheelDeltas();

        return deltas.y;
    },

<span id='Ext-EventObject-method-within'>    /**
</span>    * Returns true if the target of this event is a child of el.  Unless the allowEl parameter is set, it will return false if if the target is el.
    * Example usage:&lt;pre&gt;&lt;code&gt;
// Handle click on any child of an element
Ext.getBody().on('click', function(e){
    if(e.within('some-el')){
        alert('Clicked on a child of some-el!');
    }
});

// Handle click directly on an element, ignoring clicks on child nodes
Ext.getBody().on('click', function(e,t){
    if((t.id == 'some-el') &amp;&amp; !e.within(t, true)){
        alert('Clicked directly on some-el!');
    }
});
&lt;/code&gt;&lt;/pre&gt;
     * @param {Mixed} el The id, DOM element or Ext.core.Element to check
     * @param {Boolean} related (optional) true to test if the related target is within el instead of the target
     * @param {Boolean} allowEl {optional} true to also check if the passed element is the target or related target
     * @return {Boolean}
     */
    within : function(el, related, allowEl){
        if(el){
            var t = related ? this.getRelatedTarget() : this.getTarget(),
                result;

            if (t) {
                result = Ext.fly(el).contains(t);
                if (!result &amp;&amp; allowEl) {
                    result = t == Ext.getDom(el);
                }
                return result;
            }
        }
        return false;
    },

<span id='Ext-EventObject-method-isNavKeyPress'>    /**
</span>     * Checks if the key pressed was a &quot;navigation&quot; key
     * @return {Boolean} True if the press is a navigation keypress
     */
    isNavKeyPress : function(){
        var me = this,
            k = this.normalizeKey(me.keyCode);

       return (k &gt;= 33 &amp;&amp; k &lt;= 40) ||  // Page Up/Down, End, Home, Left, Up, Right, Down
       k == me.RETURN ||
       k == me.TAB ||
       k == me.ESC;
    },

<span id='Ext-EventObject-method-isSpecialKey'>    /**
</span>     * Checks if the key pressed was a &quot;special&quot; key
     * @return {Boolean} True if the press is a special keypress
     */
    isSpecialKey : function(){
        var k = this.normalizeKey(this.keyCode);
        return (this.type == 'keypress' &amp;&amp; this.ctrlKey) ||
        this.isNavKeyPress() ||
        (k == this.BACKSPACE) || // Backspace
        (k &gt;= 16 &amp;&amp; k &lt;= 20) || // Shift, Ctrl, Alt, Pause, Caps Lock
        (k &gt;= 44 &amp;&amp; k &lt;= 46);   // Print Screen, Insert, Delete
    },

<span id='Ext-EventObject-method-getPoint'>    /**
</span>     * Returns a point object that consists of the object coordinates.
     * @return {Ext.util.Point} point
     */
    getPoint : function(){
        var xy = this.getXY();
        return Ext.create('Ext.util.Point', xy[0], xy[1]);
    },

<span id='Ext-EventObject-method-hasModifier'>   /**
</span>    * Returns true if the control, meta, shift or alt key was pressed during this event.
    * @return {Boolean}
    */
    hasModifier : function(){
        return this.ctrlKey || this.altKey || this.shiftKey || this.metaKey;
    },

<span id='Ext-EventObject-method-injectEvent'>    /**
</span>     * Injects a DOM event using the data in this object and (optionally) a new target.
     * This is a low-level technique and not likely to be used by application code. The
     * currently supported event types are:
     * &lt;p&gt;&lt;b&gt;HTMLEvents&lt;/b&gt;&lt;/p&gt;
     * &lt;ul&gt;
     * &lt;li&gt;load&lt;/li&gt;
     * &lt;li&gt;unload&lt;/li&gt;
     * &lt;li&gt;select&lt;/li&gt;
     * &lt;li&gt;change&lt;/li&gt;
     * &lt;li&gt;submit&lt;/li&gt;
     * &lt;li&gt;reset&lt;/li&gt;
     * &lt;li&gt;resize&lt;/li&gt;
     * &lt;li&gt;scroll&lt;/li&gt;
     * &lt;/ul&gt;
     * &lt;p&gt;&lt;b&gt;MouseEvents&lt;/b&gt;&lt;/p&gt;
     * &lt;ul&gt;
     * &lt;li&gt;click&lt;/li&gt;
     * &lt;li&gt;dblclick&lt;/li&gt;
     * &lt;li&gt;mousedown&lt;/li&gt;
     * &lt;li&gt;mouseup&lt;/li&gt;
     * &lt;li&gt;mouseover&lt;/li&gt;
     * &lt;li&gt;mousemove&lt;/li&gt;
     * &lt;li&gt;mouseout&lt;/li&gt;
     * &lt;/ul&gt;
     * &lt;p&gt;&lt;b&gt;UIEvents&lt;/b&gt;&lt;/p&gt;
     * &lt;ul&gt;
     * &lt;li&gt;focusin&lt;/li&gt;
     * &lt;li&gt;focusout&lt;/li&gt;
     * &lt;li&gt;activate&lt;/li&gt;
     * &lt;li&gt;focus&lt;/li&gt;
     * &lt;li&gt;blur&lt;/li&gt;
     * &lt;/ul&gt;
     * @param {Element/HTMLElement} target If specified, the target for the event. This
     * is likely to be used when relaying a DOM event. If not specified, {@link #getTarget}
     * is used to determine the target.
     */
    injectEvent: function () {
        var API,
            dispatchers = {}; // keyed by event type (e.g., 'mousedown')

        // Good reference: http://developer.yahoo.com/yui/docs/UserAction.js.html

        // IE9 has createEvent, but this code causes major problems with htmleditor (it
        // blocks all mouse events and maybe more). TODO

        if (!Ext.isIE &amp;&amp; document.createEvent) { // if (DOM compliant)
            API = {
                createHtmlEvent: function (doc, type, bubbles, cancelable) {
                    var event = doc.createEvent('HTMLEvents');

                    event.initEvent(type, bubbles, cancelable);
                    return event;
                },

                createMouseEvent: function (doc, type, bubbles, cancelable, detail,
                                            clientX, clientY, ctrlKey, altKey, shiftKey, metaKey,
                                            button, relatedTarget) {
                    var event = doc.createEvent('MouseEvents'),
                        view = doc.defaultView || window;

                    if (event.initMouseEvent) {
                        event.initMouseEvent(type, bubbles, cancelable, view, detail,
                                    clientX, clientY, clientX, clientY, ctrlKey, altKey,
                                    shiftKey, metaKey, button, relatedTarget);
                    } else { // old Safari
                        event = doc.createEvent('UIEvents');
                        event.initEvent(type, bubbles, cancelable);
                        event.view = view;
                        event.detail = detail;
                        event.screenX = clientX;
                        event.screenY = clientY;
                        event.clientX = clientX;
                        event.clientY = clientY;
                        event.ctrlKey = ctrlKey;
                        event.altKey = altKey;
                        event.metaKey = metaKey;
                        event.shiftKey = shiftKey;
                        event.button = button;
                        event.relatedTarget = relatedTarget;
                    }

                    return event;
                },

                createUIEvent: function (doc, type, bubbles, cancelable, detail) {
                    var event = doc.createEvent('UIEvents'),
                        view = doc.defaultView || window;

                    event.initUIEvent(type, bubbles, cancelable, view, detail);
                    return event;
                },

                fireEvent: function (target, type, event) {
                    target.dispatchEvent(event);
                },

                fixTarget: function (target) {
                    // Safari3 doesn't have window.dispatchEvent()
                    if (target == window &amp;&amp; !target.dispatchEvent) {
                        return document;
                    }

                    return target;
                }
            };
        } else if (document.createEventObject) { // else if (IE)
            var crazyIEButtons = { 0: 1, 1: 4, 2: 2 };

            API = {
                createHtmlEvent: function (doc, type, bubbles, cancelable) {
                    var event = doc.createEventObject();
                    event.bubbles = bubbles;
                    event.cancelable = cancelable;
                    return event;
                },

                createMouseEvent: function (doc, type, bubbles, cancelable, detail,
                                            clientX, clientY, ctrlKey, altKey, shiftKey, metaKey,
                                            button, relatedTarget) {
                    var event = doc.createEventObject();
                    event.bubbles = bubbles;
                    event.cancelable = cancelable;
                    event.detail = detail;
                    event.screenX = clientX;
                    event.screenY = clientY;
                    event.clientX = clientX;
                    event.clientY = clientY;
                    event.ctrlKey = ctrlKey;
                    event.altKey = altKey;
                    event.shiftKey = shiftKey;
                    event.metaKey = metaKey;
                    event.button = crazyIEButtons[button] || button;
                    event.relatedTarget = relatedTarget; // cannot assign to/fromElement
                    return event;
                },

                createUIEvent: function (doc, type, bubbles, cancelable, detail) {
                    var event = doc.createEventObject();
                    event.bubbles = bubbles;
                    event.cancelable = cancelable;
                    return event;
                },

                fireEvent: function (target, type, event) {
                    target.fireEvent('on' + type, event);
                },

                fixTarget: function (target) {
                    if (target == document) {
                        // IE6,IE7 thinks window==document and doesn't have window.fireEvent()
                        // IE6,IE7 cannot properly call document.fireEvent()
                        return document.documentElement;
                    }

                    return target;
                }
            };
        }

        //----------------
        // HTMLEvents

        Ext.Object.each({
                load:   [false, false],
                unload: [false, false],
                select: [true, false],
                change: [true, false],
                submit: [true, true],
                reset:  [true, false],
                resize: [true, false],
                scroll: [true, false]
            },
            function (name, value) {
                var bubbles = value[0], cancelable = value[1];
                dispatchers[name] = function (targetEl, srcEvent) {
                    var e = API.createHtmlEvent(name, bubbles, cancelable);
                    API.fireEvent(targetEl, name, e);
                };
            });

        //----------------
        // MouseEvents

        function createMouseEventDispatcher (type, detail) {
            var cancelable = (type != 'mousemove');
            return function (targetEl, srcEvent) {
                var xy = srcEvent.getXY(),
                    e = API.createMouseEvent(targetEl.ownerDocument, type, true, cancelable,
                                detail, xy[0], xy[1], srcEvent.ctrlKey, srcEvent.altKey,
                                srcEvent.shiftKey, srcEvent.metaKey, srcEvent.button,
                                srcEvent.relatedTarget);
                API.fireEvent(targetEl, type, e);
            };
        }

        Ext.each(['click', 'dblclick', 'mousedown', 'mouseup', 'mouseover', 'mousemove', 'mouseout'],
            function (eventName) {
                dispatchers[eventName] = createMouseEventDispatcher(eventName, 1);
            });

        //----------------
        // UIEvents

        Ext.Object.each({
                focusin:  [true, false],
                focusout: [true, false],
                activate: [true, true],
                focus:    [false, false],
                blur:     [false, false]
            },
            function (name, value) {
                var bubbles = value[0], cancelable = value[1];
                dispatchers[name] = function (targetEl, srcEvent) {
                    var e = API.createUIEvent(targetEl.ownerDocument, name, bubbles, cancelable, 1);
                    API.fireEvent(targetEl, name, e);
                };
            });

        //---------
        if (!API) {
            // not even sure what ancient browsers fall into this category...

            dispatchers = {}; // never mind all those we just built :P

            API = {
                fixTarget: function (t) {
                    return t;
                }
            };
        }

        function cannotInject (target, srcEvent) {
            //&lt;debug&gt;
            // TODO log something
            //&lt;/debug&gt;
        }

        return function (target) {
            var me = this,
                dispatcher = dispatchers[me.type] || cannotInject,
                t = target ? (target.dom || target) : me.getTarget();

            t = API.fixTarget(t);
            dispatcher(t, me);
        };
    }() // call to produce method

}, function() {

Ext.EventObject = new Ext.EventObjectImpl();

});

</pre>
</body>
</html>
